package com.ai.common.advice;

import com.ai.common.CommonResponse;
import com.ai.common.exception.JeecgBoot400Exception;
import com.ai.common.exception.JeecgBoot401Exception;
import com.ai.common.exception.JeecgBootException;
import lombok.extern.slf4j.Slf4j;
import org.springframework.dao.DataIntegrityViolationException;
import org.springframework.dao.DuplicateKeyException;
import org.springframework.data.redis.connection.PoolException;
import org.springframework.http.HttpStatus;
import org.springframework.validation.BindingResult;
import org.springframework.web.HttpRequestMethodNotSupportedException;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseStatus;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import org.springframework.web.multipart.MaxUploadSizeExceededException;
import org.springframework.web.servlet.NoHandlerFoundException;

import java.util.HashMap;


/**
 * 异常处理器
 *
 * @Author scott
 * @Date 2019
 */
@Slf4j
@RestControllerAdvice
public class GlobalExceptionAdvice {

    /**
     * 处理自定义异常
     */
    @ExceptionHandler(value = JeecgBoot400Exception.class)
    public CommonResponse handleJeecgBoot400Exception(JeecgBoot400Exception e) {
        CommonResponse response = new CommonResponse(-1, "business error");
        response.setData(e.getMessage());
        log.error("commerce service has error: [{}]", e.getMessage(), e);
        return response;
    }

    /**
     * 处理自定义异常
     */
    @ExceptionHandler(value = JeecgBoot401Exception.class)
    @ResponseStatus(HttpStatus.UNAUTHORIZED)
    public CommonResponse<String> handleJeecgBoot401Exception(JeecgBoot401Exception e) {
        log.error(e.getMessage(), e);
        return CommonResponse.error(401, e.getMessage());
    }

    /**
     * 处理自定义异常
     */
    @ExceptionHandler(value = JeecgBootException.class)
    public CommonResponse<String> handleJeecgBootException(JeecgBootException e) {
        log.error(e.getMessage(), e);
        return CommonResponse.error(e.getMessage());
    }

    @ExceptionHandler(value = NoHandlerFoundException.class)
    public CommonResponse<String> handlerNoFoundException(Exception e) {
        log.error(e.getMessage(), e);
        return CommonResponse.error(404, "路径不存在，请检查路径是否正确");
    }

    @ExceptionHandler(value = DuplicateKeyException.class)
    public CommonResponse<String> handleDuplicateKeyException(DuplicateKeyException e) {
        log.error(e.getMessage(), e);
        return CommonResponse.error("数据库中已存在该记录");
    }


    /**
     * @param e
     * @return
     */
    @ExceptionHandler(value = HttpRequestMethodNotSupportedException.class)
    public CommonResponse<String> HttpRequestMethodNotSupportedException(HttpRequestMethodNotSupportedException e) {
        StringBuffer sb = new StringBuffer();
        sb.append("不支持");
        sb.append(e.getMethod());
        sb.append("请求方法，");
        sb.append("支持以下");
        String[] methods = e.getSupportedMethods();
        if (methods != null) {
            for (String str : methods) {
                sb.append(str);
                sb.append("、");
            }
        }
        log.error(sb.toString(), e);
        return CommonResponse.error(405, sb.toString());
    }

    /**
     * spring默认上传大小100MB 超出大小捕获异常MaxUploadSizeExceededException
     */
    @ExceptionHandler(value = MaxUploadSizeExceededException.class)
    public CommonResponse<String> handleMaxUploadSizeExceededException(MaxUploadSizeExceededException e) {
        log.error(e.getMessage(), e);
        return CommonResponse.error("文件大小超出10MB限制, 请压缩或降低文件质量! ");
    }

    @ExceptionHandler(value = DataIntegrityViolationException.class)
    public CommonResponse<String> handleDataIntegrityViolationException(DataIntegrityViolationException e) {
        log.error(e.getMessage(), e);
        return CommonResponse.error("字段太长,超出数据库字段的长度");
    }

    @ExceptionHandler(value = PoolException.class)
    public CommonResponse<String> handlePoolException(PoolException e) {
        log.error(e.getMessage(), e);
        return CommonResponse.error("Redis 连接异常!");
    }


    @ExceptionHandler(value = MethodArgumentNotValidException.class)
    public CommonResponse validExceptionHandler(MethodArgumentNotValidException e){
        log.error("数据校验出现异常：{}，异常类型：{}",e.getMessage(),e.getClass());
        BindingResult result = e.getBindingResult();

        HashMap<String, String> map = new HashMap<>();
        result.getFieldErrors().forEach((item)->{
            //获取校验的错误结果
            String defaultMessage = item.getDefaultMessage();
            //获取校验出错的属性名
            String field = item.getField();
            map.put(field,defaultMessage);
        });
        return CommonResponse.error("字段校验异常").setData(map);
    }


    @ExceptionHandler(value = Exception.class)
    public CommonResponse<String> handleException(Exception e) {
        log.error(e.getMessage(), e);
        return CommonResponse.error("操作失败，" + e.getMessage());
    }
}
